package cn.com.surker.wechat;

import cn.com.surker.common.HttpRequestHelper;
import cn.com.surker.redis.RedisUtils;
import cn.com.surker.spring.SpringContextHolder;
import cn.com.surker.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * @Author lucky
 * @create 2021年03月24 14:53
 * @desc
 */
public class WechatOaTestGroupApi {

    private static Logger log = LoggerFactory.getLogger(WechatOaTestGroupApi.class);

    /**企业微信的**/
    public static String corpID = "wwd85ae41a2d988bc8";
//    /**企业微信密匙**/
//    public static String corpSecret = "v8VgA-JM7T7s8G5JfTqYFDbYcR3H_om09jkcBHAttUc";
    /**OA密匙**/
    public static String corpSecret = "Xdem8AnDfq7XEgl5b81jrwq06HewdQUR7VFRxo9saHM";
    /**修改部门成员信息**/
    public static String corpOriginSecret = "DmnCDnbHi6R9us3yHYXf68IvC-ESfJeTbSnFlU4exV0";
    /**应用ID**/
    public static String agentId = "1000019";
    /**缓存键**/
    public static String accessTokenKey = "oa_test_cloud_access_token_key";
    /**修改token**/
    public static String accessOriginTokenKey = "oa_test_cloud_origin_access_token";

    public static String ticketKey = "group_surker_cloud_js_ticket";
    /**缓存时间**/
    public static Long sessionExpired = 7200L;

    // 创建部门url
    public static String createOrgUrl = "https://qyapi.weixin.qq.com/cgi-bin/department/create";
    // 更新部门url
    public static String updateOrgUrl = "https://qyapi.weixin.qq.com/cgi-bin/department/update";
    // 删除部门url
    public static String deleteOrgUrl = "https://qyapi.weixin.qq.com/cgi-bin/department/delete";
    // 同步部门url
    public static String synOrgUrl = "https://qyapi.weixin.qq.com/cgi-bin/department/simplelist";

    // 新增用户url
    public static String createUserUrl = "https://qyapi.weixin.qq.com/cgi-bin/user/create";
    // 更新用户url
    public static String updateUserUrl = "https://qyapi.weixin.qq.com/cgi-bin/user/update";
    // 删除用户url
    public static String deleteUrl = "https://qyapi.weixin.qq.com/cgi-bin/user/delete";

    public static void main(String[] args){

//        getUser("wwd85ae41a2d988bc8", "v8VgA-JM7T7s8G5JfTqYFDbYcR3H_om09jkcBHAttUc", "lucky");

//        String touser = "lucky|1mj1482|1lgq996|1lt1556";
//        String msgType = "textcard";
//        String title = "驰旭集团生产早汇报";
//        String description = "驰旭集团生产2021年12月15日";
//        String url2 = "http://surker.chixugroup.com/cloud/index";
//        Boolean boo = sendTextCardMessage(touser, msgType, title, description, url2);
        String token = "U7J2QXB8Cann3djaLUFBfqPVUaghE1cmRI1GGVglQLqGWh79V_A1h-Fydt8mCZJYMIgBJv1mHq5tEF6-SXyI25QF7Fz3KitI_4QfuvJG9OmrE6ryme5rXQaJcCd5EE-0x81uyCG8p8aOC2jsm7qFfJA_cIXrlb_3K1q5KAi7i_lsq_EzxlX_1pk_443sgb3dW9XAYIzYcBdAfnS9xLmDMA";
//
//        String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpID + "&corpsecret=" + corpOriginSecret;
//
        String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpID + "&corpsecret=" + corpSecret;
//        sendTextCardMessage (token, "lucky|1lt1556", "textcard", "测试111", "textcardtextcardtextcard",
//                "http://surker.chixugroup.com/cloud/order/records?title=122332fererwe");
//        JSONObject json = new JSONObject();
//        json.put("id", 318);
//        JSONObject j = deleteUserOrDepartment(corpID, corpOriginSecret,
//                "https://qyapi.weixin.qq.com/cgi-bin/department/delete", json);
//        System.out.println(j);
        sendButtonMessage(corpID, corpSecret, agentId, "lucky", "button_interaction", "测试项目",
                "材料付款--流程编号:CXM00011,申请人:万强,付款合同:测试大,总金额:4343.0元", null, "http://surker.chixugroup.com");
//        updateCardMessage(null, null, null, null, null, "");
//        sendCardMessage(null, null, null, null, null, null, null, null);
//        try {
//            String res = HttpRequestHelper.get(url);
//            JSONObject obj = JSONObject.parseObject(res);
//            System.out.println(obj);
//            log.info("企业微信获取access_token:{},token_url:{}", res, url);
//            if("ok".equals(obj.getString("errmsg"))){
//                log.info("验证后的access_token:{}", obj.getString("access_token"));
//            } else {
//                log.error("获取企业微信API token失败：" + res);
//            }
//        } catch (Exception e) {
//            log.error("获取企业微信API token失败：" + e.getMessage(), e);
//        }
    }

    /**
     * 获取企业微信应用的JS_Ticket
     * @return
     */
    public static String getAgentJsTicket(String corpid, String secret) {
        if (StringUtils.isNull(corpid))
            corpid = corpID;
        if (StringUtils.isNull(secret))
            secret = corpSecret;
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        String key = corpid + "_" + ticketKey;
        /**判断ticket签名是否存在**/
        if (redisUtils.exists(key)) {
            return StringUtils.convertString(redisUtils.get(key));
        }
        String accessToken = loadGroupToken(corpid, secret);
        String url = "https://qyapi.weixin.qq.com/cgi-bin/ticket/get?access_token=" + accessToken + "&type=agent_config";
        try {
            String res = HttpRequestHelper.get(url);
            JSONObject obj = JSONObject.parseObject(res);
            if(obj.getInteger("errcode") == 0 && !StringUtils.isNull(obj.getString("ticket"))){
                log.info("ticket=" + obj.getString("ticket"));
                redisUtils.set(key, obj.getString("ticket"), sessionExpired);
                return obj.getString("ticket");
            } else if (obj != null && obj.getInteger("errcode") == 40001) {
                redisUtils.remove(accessTokenKey);
                return getAgentJsTicket(corpid, secret);
            } else {
                log.error("获取企业微信应用API JS_Ticket失败：" + res);
                return "";
            }
        } catch (Exception e) {
            log.error("获取企业微信应用API JS_Ticket失败：" + e.getMessage(), e);
            return "";
        }
    }

    /**
     * 企业微信加密签名
     * @param nonceStr
     * @param url
     * @param ticket
     * @param timestamp
     * @return
     */
    public static String jsApiSignature(String nonceStr, String url, String ticket, Long timestamp){
        String str = "jsapi_ticket=" + ticket + "&noncestr=" + nonceStr + "&timestamp=" + timestamp + "&url="+url;
        log.error("jsApiSign sinStr:" + str);
        String signature = WechatAccountApi.sha1(str).toLowerCase();
        log.error("jsApiSign signature:" + signature);
        return signature;
    }

    /**
     * 获取企业微信的JS_Ticket
     * @return
     */
    public static String getJsTicket(String corpid, String secret) {
        if (StringUtils.isNull(corpid))
            corpid = corpID;
        if (StringUtils.isNull(secret))
            secret = corpSecret;
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        String key = corpid + "_" + ticketKey;
        /**判断ticket签名是否存在**/
        if (redisUtils.exists(key)) {
            return StringUtils.convertString(redisUtils.get(key));
        }
        String tokenKey = corpid + "_" + accessTokenKey;
        String accessToken = "";
        if(redisUtils.exists(tokenKey))
            accessToken = StringUtils.convertString(redisUtils.get(tokenKey));
        else
            accessToken = loadGroupToken(corpid, secret);
        String url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=" + accessToken;
        try {
            String res = HttpRequestHelper.get(url);
            JSONObject obj = JSONObject.parseObject(res);
            if(obj.getInteger("errcode") == 0 && !StringUtils.isNull(obj.getString("ticket"))){
                log.info("ticket=" + obj.getString("ticket"));
                redisUtils.set(key, obj.getString("ticket"), sessionExpired);
                return obj.getString("ticket");
            } else if (obj != null && obj.getInteger("errcode") == 40001) {
                redisUtils.remove(tokenKey);
                loadGroupToken(corpid, secret);
                return getJsTicket(corpid, secret);
            } else {
                log.error("获取企业微信API JS_Ticket失败：" + res);
                return "";
            }
        } catch (Exception e) {
            log.error("获取企业微信API JS_Ticket失败：" + e.getMessage(), e);
            return "";
        }
    }

    /**
     * 创建用户&部门
     * @param corpid 企业微信CORPID
     * @param url 用户 https://qyapi.weixin.qq.com/cgi-bin/user/create
     *           部门 https://qyapi.weixin.qq.com/cgi-bin/department/create
     * @param url 用户 https://qyapi.weixin.qq.com/cgi-bin/user/update
     *            部门 https://qyapi.weixin.qq.com/cgi-bin/department/update
     * @param originSecret
     * @param jsonObject
     * @return
     */
    public static JSONObject updateUserOrDepartment(String corpid, String originSecret, String url, JSONObject jsonObject) {
        if (StringUtils.isNull(corpid))
            corpid = corpID;
        if (StringUtils.isNull(originSecret))
            originSecret = corpOriginSecret;
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        String tokenKey = corpid + "_" + accessOriginTokenKey;
        if(!redisUtils.exists(tokenKey))
            loadGroupOriginToken(corpid, originSecret);
        try {
            String access_token = StringUtils.convertString(redisUtils.get(tokenKey));

            jsonObject.put("access_token", access_token);
            /**消息请求地址**/
            String postUrl = url + "?access_token=" + access_token;
            /**请求结果**/
            String result = HttpRequestHelper.sendJsonPost(postUrl, jsonObject.toJSONString());
            JSONObject obj = JSONObject.parseObject(result);
            Integer code = obj.getInteger("errcode");
            System.out.println(result);
            if(code == 0){
                return obj;

            } else if (code == 42001 || code == 40014){//token失效
                log.error("创建企业微信用户token失效，重新获取token");
                redisUtils.remove(tokenKey);
                loadGroupOriginToken(corpid, originSecret);
                return updateUserOrDepartment(corpid, originSecret, url, jsonObject);
            } else {
                log.error("创建企业微信用户失败：" + result);
                return null;
            }
        } catch (Exception e) {
            log.error("创建企业微信用户失败：" + e.getMessage(), e);
        }
        return null;
    }

    /**
     * 删除企业用户
     * @param corpid
     * @param originSecret
     * @param url 用户 https://qyapi.weixin.qq.com/cgi-bin/user/delete
     * 部门 https://qyapi.weixin.qq.com/cgi-bin/department/delete
     * @param jsonObject
     * @return
     */
    public static JSONObject deleteUserOrDepartment(String corpid, String originSecret, String url, JSONObject jsonObject) {
        if (StringUtils.isNull(corpid))
            corpid = corpID;
        if (StringUtils.isNull(originSecret))
            originSecret = corpOriginSecret;
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        String tokenKey = corpid + "_" + accessOriginTokenKey;
        String access_token = "";
        if(!redisUtils.exists(tokenKey))
            access_token = loadGroupOriginToken(corpid, originSecret);
        else
            access_token = StringUtils.convertString(redisUtils.get(tokenKey));
        try {

//            jsonObject.put("access_token", access_token);
            /**消息请求地址**/
            String postUrl = url + "?access_token=" + access_token;
            for (String key : jsonObject.keySet()) {
                postUrl += "&" + key + "=" + jsonObject.get(key);
            }
            /**请求结果**/
            String result = HttpRequestHelper.get(postUrl);
            JSONObject obj = JSONObject.parseObject(result);
            Integer code = obj.getInteger("errcode");
            System.out.println(result);
            if(code == 0){
                return obj;

            } else if (code == 42001 || code == 40014){//token失效
                log.error("删除企业微信用户token失效，重新获取token");
                redisUtils.remove(tokenKey);
                loadGroupOriginToken(corpid, originSecret);
                return deleteUserOrDepartment(corpid, originSecret, url, jsonObject);
            } else {
                log.error("删除企业微信用户token失效：" + result);
                return null;
            }
        } catch (Exception e) {
            log.error("删除企业微信用户token失效：" + e.getMessage(), e);
        }
        return null;
    }

    /**
     * 获取用户信息
     * @param corpid 企业微信应用ID
     * @param secret 应用secret
     * @param username
     * @return
     */
    public static JSONObject getUser(String corpid, String secret, String username) {
        if (StringUtils.isNull(corpid))
            corpid = corpID;
        if (StringUtils.isNull(secret))
            secret = corpSecret;
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        String tokenKey = corpid + "_" + accessTokenKey;
        String accessToken = "";
        if(redisUtils.exists(tokenKey))
            accessToken = StringUtils.convertString(redisUtils.get(tokenKey));
        else
            accessToken = loadGroupToken(corpid, secret);
        try {

            /**消息请求地址**/
            String postUrl = "https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token=" + accessToken + "&userid=" + username;
            /**请求结果**/
            String result = HttpRequestHelper.get(postUrl);
            JSONObject obj = JSONObject.parseObject(result);
            Integer code = obj.getInteger("errcode");
            System.out.println(result);
            if(code == 0){
                return obj;

            } else if (code == 42001 || code == 40014 || code == 41001){//token失效
                log.error("企业微信用户信息验证token失效，重新获取token");
                redisUtils.remove(tokenKey);
                loadGroupToken(corpid, secret);
                return getUser(corpid, secret, username);
            } else {
                log.error("企业微信获取用户信息失败：" + result);
                return null;
            }
        } catch (Exception e) {
            log.error("获取企业微信用户信息失败：" + e.getMessage(), e);
        }
        return null;
    }

    /**
     * 企业微信推送信息
     * @param touser 接收用户
     * @param msgType 消息类型news
     * @return
     */
    public static Boolean sendTextImageMessage(String token,String touser, String msgType, JSONObject newsJson) {
        /**请求参数**/
        JSONObject json = new JSONObject();

        json.put("touser", touser);
        json.put("msgtype", msgType);
        json.put("agentid", agentId);
        json.put("news", newsJson);
        try {
            /**消息请求地址**/
            String postUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + token;
            /**请求结果**/
            String result = HttpRequestHelper.senPostJson(postUrl, json.toJSONString());
            JSONObject obj = JSONObject.parseObject(result);
            Integer code = obj.getInteger("errcode");
            if(code == 0){
                return true;
            } else {
                log.error("企业微信推送信息失败：" + result);
                return false;
            }
        } catch (Exception e) {
            log.error("获取企业微信用户信息失败：" + e.getMessage(), e);
            return false;
        }
    }

    /**
     * 企业微信推送信息
     * @param corpid 企业微信应用ID
     * @param secret 应用secret
     * @param touser 接收用户
     * @param msgType 消息类型news
     * @return
     */
    public static Boolean sendTextImageMessage(String corpid, String secret,String touser,
                                               String msgType, JSONObject newsJson) {
        if (StringUtils.isNull(corpid))
            corpid = corpID;
        if (StringUtils.isNull(secret))
            secret = corpSecret;
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        String tokenKey = corpid + "_" + accessTokenKey;
        String accessToken = "";
        if(redisUtils.exists(tokenKey))
            accessToken = StringUtils.convertString(redisUtils.get(tokenKey));
        else
            accessToken = loadGroupToken(corpid, secret);
        /**请求参数**/
        JSONObject json = new JSONObject();

        json.put("touser", touser);
        json.put("msgtype", msgType);
        json.put("agentid", agentId);
        json.put("news", newsJson);
        try {
            /**消息请求地址**/
            String postUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + accessToken;
            /**请求结果**/
            String result = HttpRequestHelper.senPostJson(postUrl, json.toJSONString());
            JSONObject obj = JSONObject.parseObject(result);
            Integer code = obj.getInteger("errcode");
            if(code == 0){
                return true;
            } else if (code == 42001 || code == 40014 || code == 41001){//token失效
                log.error("企业微信用户验证token失效，重新获取token");
                redisUtils.remove(tokenKey);
                loadGroupToken(corpid, secret);
                return sendTextImageMessage(corpid, secret, touser, msgType, newsJson);
            } else {
                log.error("企业微信推送信息失败：" + result);
                return false;
            }
        } catch (Exception e) {
            log.error("获取企业微信用户信息失败：" + e.getMessage(), e);
            return false;
        }
    }

    /**
     * 企业微信推送信息
     * @param touser 接收用户
     * @param msgType 消息类型
     * @param title 标题
     * @param description 描述
     * @param url 跳转地址
     * @return
     */
    public static Boolean sendTextCardMessage(String token, String touser, String msgType, String title, String description, String url) {
        /**请求参数**/
        JSONObject textJson = new JSONObject();
        JSONObject json = new JSONObject();
        textJson.put("title", title);
        textJson.put("description", description);
        textJson.put("url", url);

        json.put("touser", touser);
        json.put("msgtype", msgType);
        json.put("agentid", agentId);
        json.put("textcard", textJson);
        try {
            /**消息请求地址**/
            String postUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + token;
            /**请求结果**/
            String result = HttpRequestHelper.senPostJson(postUrl, json.toJSONString());
            System.out.println(result);

            JSONObject obj = JSONObject.parseObject(result);
            Integer code = obj.getInteger("errcode");
            if(code == 0){
                return true;
            } else {
                log.error("企业微信推送信息失败：" + result);
                return false;
            }
        } catch (Exception e) {
            log.error("获取企业微信用户信息失败：" + e.getMessage(), e);
            return false;
        }
    }

    /**
     * 企业微信推送信息
     * @param corpid 企业微信应用ID
     * @param secret 应用secret
     * @param touser 接收用户
     * @param content 描述
     * @return
     */
    public static Boolean sendTextMessage(String corpid, String secret, String agentid, String touser, String content) {
        if (StringUtils.isNull(corpid))
            corpid = corpID;
        if (StringUtils.isNull(secret))
            secret = corpSecret;
        if (StringUtils.isNull(agentid))
            agentid = agentId;
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        String tokenKey = corpid + "_" + accessTokenKey;
        String accessToken = "";
        if(redisUtils.exists(tokenKey))
            accessToken = StringUtils.convertString(redisUtils.get(tokenKey));
        else
            accessToken = loadGroupToken(corpid, secret);
        /**请求参数**/
        JSONObject textJson = new JSONObject();
        JSONObject json = new JSONObject();
        textJson.put("content", content);

        json.put("touser", touser);
        json.put("agentid", agentid);
        json.put("msgtype", "text");
        json.put("text", textJson);
        try {
            /**消息请求地址**/
            String postUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + accessToken;
            /**请求结果**/
            String result = HttpRequestHelper.senPostJson(postUrl, json.toJSONString());
            JSONObject obj = JSONObject.parseObject(result);
            Integer code = obj.getInteger("errcode");
            if(code == 0){
                return true;
            } else if (code == 42001 || code == 40014 || code == 41001){//token失效
                log.error("企业微信用户验证token失效，重新获取token");
                redisUtils.remove(tokenKey);
                loadGroupToken(corpid, secret);
                return sendTextMessage(corpid, secret, touser, content);
            } else {
                log.error("企业微信推送信息失败：" + result);
                return false;
            }
        } catch (Exception e) {
            log.error("获取企业微信用户信息失败：" + e.getMessage(), e);
            return false;
        }
    }

    /**
     * 企业微信推送信息
     * @param corpid 企业微信应用ID
     * @param secret 应用secret
     * @param touser 接收用户
     * @param content 描述
     * @return
     */
    public static Boolean sendTextMessage(String corpid, String secret, String touser, String content) {
        if (StringUtils.isNull(corpid))
            corpid = corpID;
        if (StringUtils.isNull(secret))
            secret = corpSecret;
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        String tokenKey = corpid + "_" + accessTokenKey;
        String accessToken = "";
        if(redisUtils.exists(tokenKey))
            accessToken = StringUtils.convertString(redisUtils.get(tokenKey));
        else
            accessToken = loadGroupToken(corpid, secret);
        /**请求参数**/
        JSONObject textJson = new JSONObject();
        JSONObject json = new JSONObject();
        textJson.put("content", content);

        json.put("touser", touser);
        json.put("agentid", agentId);
        json.put("msgtype", "text");
        json.put("text", textJson);
        try {
            /**消息请求地址**/
            String postUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + accessToken;
            /**请求结果**/
            String result = HttpRequestHelper.senPostJson(postUrl, json.toJSONString());
            JSONObject obj = JSONObject.parseObject(result);
            Integer code = obj.getInteger("errcode");
            if(code == 0){
                return true;
            } else if (code == 42001 || code == 40014 || code == 41001){//token失效
                log.error("企业微信用户验证token失效，重新获取token");
                redisUtils.remove(tokenKey);
                loadGroupToken(corpid, secret);
                return sendTextMessage(corpid, secret, touser, content);
            } else {
                log.error("企业微信推送信息失败：" + result);
                return false;
            }
        } catch (Exception e) {
            log.error("获取企业微信用户信息失败：" + e.getMessage(), e);
            return false;
        }
    }

    /**
     * 企业微信推送信息
     * @param corpid 企业微信应用ID
     * @param secret 应用secret
     * @param touser 接收用户
     * @param msgType textcard 消息类型
     * @param title 标题
     * @param description 描述
     * @param url 跳转地址
     * @return
     */
    public static Boolean sendTextCardMessage(String corpid, String secret, String touser, String msgType,
                                              String title, String description, String url) {
        if (StringUtils.isNull(corpid))
            corpid = corpID;
        if (StringUtils.isNull(secret))
            secret = corpSecret;
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        String tokenKey = corpid + "_" + accessTokenKey;
        String accessToken = "";
        if(redisUtils.exists(tokenKey))
            accessToken = StringUtils.convertString(redisUtils.get(tokenKey));
        else
            accessToken = loadGroupToken(corpid, secret);
        /**请求参数**/
        JSONObject textJson = new JSONObject();
        JSONObject json = new JSONObject();
        textJson.put("title", title);
        textJson.put("description", description);
        textJson.put("url", url);

        json.put("touser", touser);
        json.put("msgtype", msgType);
        json.put("agentid", agentId);
        json.put("textcard", textJson);
        try {
            /**消息请求地址**/
            String postUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + accessToken;
            /**请求结果**/
            String result = HttpRequestHelper.senPostJson(postUrl, json.toJSONString());
            System.out.println(result);
            JSONObject obj = JSONObject.parseObject(result);
            Integer code = obj.getInteger("errcode");
            if(code == 0){
                return true;
            } else if (code == 42001 || code == 40014 || code == 41001){//token失效
                log.error("企业微信用户验证token失效，重新获取token");
                redisUtils.remove(tokenKey);
                loadGroupToken(corpid, secret);
                return sendTextCardMessage(corpid, secret, touser, msgType, title, description, url);
            } else {
                log.error("企业微信推送信息失败：" + result);
                return false;
            }
        } catch (Exception e) {
            log.error("获取企业微信用户信息失败：" + e.getMessage(), e);
            return false;
        }
    }

    /**
     * 企业微信推送信息
     * @param corpid 企业微信应用ID
     * @param secret 应用secret
     * @param touser 接收用户
     * @param msgType textcard 消息类型
     * @param agent 应用ID
     * @param title 标题
     * @param description 描述
     * @param url 跳转地址
     * @return
     */
    public static Boolean sendTextCardMessage(String corpid, String secret, String agent, String touser, String msgType,
                                              String title, String description, String url) {
        if (StringUtils.isNull(corpid))
            corpid = corpID;
        if (StringUtils.isNull(secret))
            secret = corpSecret;
        if (StringUtils.isNull(agent))
            agent = agentId;

        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        String tokenKey = corpid + "_" + accessTokenKey;
        String accessToken = "";
        if(redisUtils.exists(tokenKey))
            accessToken = StringUtils.convertString(redisUtils.get(tokenKey));
        else
            accessToken = loadGroupToken(corpid, secret);
        /**请求参数**/
        JSONObject textJson = new JSONObject();
        JSONObject json = new JSONObject();
        textJson.put("title", title);
        textJson.put("description", description);
        textJson.put("url", url);

        json.put("touser", touser);
        json.put("msgtype", msgType);
        json.put("agentid", agent);
        json.put("textcard", textJson);
        try {
            /**消息请求地址**/
            String postUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + accessToken;
            /**请求结果**/
            String result = HttpRequestHelper.senPostJson(postUrl, json.toJSONString());
            System.out.println(result);
            JSONObject obj = JSONObject.parseObject(result);
            Integer code = obj.getInteger("errcode");
            if(code == 0){
                return true;
            } else if (code == 42001 || code == 40014 || code == 41001){//token失效
                log.error("企业微信用户验证token失效，重新获取token");
                redisUtils.remove(tokenKey);
                loadGroupToken(corpid, secret);
                return sendTextCardMessage(corpid, secret, touser, msgType, title, description, url);
            } else {
                log.error("企业微信推送信息失败：" + result);
                return false;
            }
        } catch (Exception e) {
            log.error("获取企业微信用户信息失败：" + e.getMessage(), e);
            return false;
        }
    }

    /**
     * 更新卡片应用按钮状态
     * @param corpid 企业应用ID
     * @param secret 密匙
     * @param agent 应用
     * @param touser 推送人员
     * @param responseCode 调用企业微信消息推送后返回code 有效性72小时
     * @param examineText 审核文字(如：通过、拒绝、已审核等)
     * @return
     */
    public static Boolean updateCardMessage(String corpid, String secret, String agent, JSONArray touser, String responseCode, String examineText) {
        if (StringUtils.isNull(corpid))
            corpid = corpID;
        if (StringUtils.isNull(secret))
            secret = corpSecret;
        if (StringUtils.isNull(agent))
            agent = agentId;
        if (StringUtils.isNull(examineText))
            examineText = "已审核";

        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        String tokenKey = corpid + "_" + accessTokenKey;
        String accessToken = "";
        if(redisUtils.exists(tokenKey))
            accessToken = StringUtils.convertString(redisUtils.get(tokenKey));
        else
            accessToken = loadGroupToken(corpid, secret);
        /**请求参数**/
        JSONObject json = new JSONObject();

        JSONObject replace = new JSONObject();
        replace.put("replace_name", examineText);
        json.put("userids", touser);
        json.put("agentid", agent);
        json.put("button", replace);
        json.put("response_code", responseCode);
        try {
//            String access_token = "Mz-R9jeNraNg81oNbEjcZkGgZ_pdZ76gEagiH-J3ZtwUL0xE_gL9CXpkur7ZkoXXvkV_GQcGH8Z2RoL5nLbiWR2ULPGFQ15NQ-S7ouXIeX_aAJj8LiQZ84FEdk8MEGCz2UKL8r4H4l2mQMcRcuG9iRgEunlm36cOEN3Te3Xi_Z7dwJOpAH8Z6wbpoKiBxW7uX26PTfEFGtwNeM9ExHAxfw";
            /**消息请求地址**/
            String postUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/update_template_card?access_token=" + accessToken;
            /**请求结果**/
            String result = HttpRequestHelper.senPostJson(postUrl, json.toJSONString());
            System.out.println(result);
            JSONObject obj = JSONObject.parseObject(result);
            Integer code = obj.getInteger("errcode");
            if(code == 0){
                return true;
            } else if (code == 42001 || code == 40014 || code == 41001){//token失效
                log.error("企业微信用户验证token失效，重新获取token");
                redisUtils.remove(tokenKey);
                loadGroupToken(corpid, secret);
                return updateCardMessage(corpid, secret, agent, touser, responseCode, examineText);
            } else {
                log.error("企业微信推送信息失败：" + result);
                return false;
            }
        } catch (Exception e) {
            log.error("获取企业微信用户信息失败：" + e.getMessage(), e);
            return false;
        }
    }

    /**
     * 批量核销更新卡片应用按钮状态
     * @param corpid 企业应用ID
     * @param secret 密匙
     * @param agent 应用
     * @param tousers 推送人员
     * @param codes 调用企业微信消息推送后返回code 有效性72小时
     * @param examineText 审核文字(如：通过、拒绝、已审核等)
     * @return
     */
    public static Boolean updateBatchCardMessage(String corpid, String secret, String agent, String[] tousers, String[] codes, String examineText) {
        if (StringUtils.isNull(corpid))
            corpid = corpID;
        if (StringUtils.isNull(secret))
            secret = corpSecret;
        if (StringUtils.isNull(agent))
            agent = agentId;
        if (StringUtils.isNull(examineText))
            examineText = "已审核";
        if (tousers == null || tousers.length == 0 || codes == null
                || codes.length == 0 || tousers.length != codes.length)
            return null;

        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        String tokenKey = corpid + "_" + accessTokenKey;
        String accessToken = "";
        if(redisUtils.exists(tokenKey))
            accessToken = StringUtils.convertString(redisUtils.get(tokenKey));
        else
            accessToken = loadGroupToken(corpid, secret);
        try {
//            String access_token = "Mz-R9jeNraNg81oNbEjcZkGgZ_pdZ76gEagiH-J3ZtwUL0xE_gL9CXpkur7ZkoXXvkV_GQcGH8Z2RoL5nLbiWR2ULPGFQ15NQ-S7ouXIeX_aAJj8LiQZ84FEdk8MEGCz2UKL8r4H4l2mQMcRcuG9iRgEunlm36cOEN3Te3Xi_Z7dwJOpAH8Z6wbpoKiBxW7uX26PTfEFGtwNeM9ExHAxfw";
            /**消息请求地址**/
            String postUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/update_template_card?access_token=" + accessToken;
            for (int i = 0; i < tousers.length; i++) {

                /**请求参数**/
                JSONObject json = new JSONObject();

                JSONObject replace = new JSONObject();
                replace.put("replace_name", examineText);
                json.put("userids", tousers[i]);
                json.put("agentid", agent);
                json.put("button", replace);
                json.put("response_code", codes[i]);

                /**请求结果**/
                String result = HttpRequestHelper.senPostJson(postUrl, json.toJSONString());
                System.out.println(result);
                JSONObject obj = JSONObject.parseObject(result);
                Integer code = obj.getInteger("errcode");
                if (code == 42001 || code == 40014 || code == 41001){//token失效
                    log.error("企业微信用户验证token失效，重新获取token");
                    redisUtils.remove(tokenKey);
                    loadGroupToken(corpid, secret);
                    return updateBatchCardMessage(corpid, secret, agent, tousers, codes, examineText);
                }
            }

            return true;
        } catch (Exception e) {
            log.error("获取企业微信用户信息失败：" + e.getMessage(), e);
            return false;
        }
    }

    /**
     * 批量发送按钮消息
     * @param corpid 企业微信ID
     * @param secret 密匙
     * @param agent 应用ID
     * @param tousers 发送用户(多个|隔开)
     * @param msgType 消息类型(见企业微信文档)
     * @param title 标题
     * @param subTitle 副标题
     * @param jsonArray 发送内容
     * @param urls 跳转url
     * @return
     */
    public static List<Map<String, Object>> sendBatchButtonMessage(String corpid, String secret, String agent, String msgType, String title,
                                                                   String subTitle, JSONArray jsonArray, String[] tousers, String[] urls) {
        if (StringUtils.isNull(corpid))
            corpid = corpID;
        if (StringUtils.isNull(secret))
            secret = corpSecret;
        if (StringUtils.isNull(agent))
            agent = agentId;
        if (StringUtils.isNull(msgType))
            msgType = "button_interaction";
        if (jsonArray == null || jsonArray.size() == 0)
            return null;
        if (tousers == null || tousers.length == 0 || urls == null
                || urls.length == 0 || tousers.length != urls.length)
            return null;

        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        String tokenKey = corpid + "_" + accessTokenKey;
        String accessToken = "";
        if(redisUtils.exists(tokenKey))
            accessToken = StringUtils.convertString(redisUtils.get(tokenKey));
        else
            accessToken = loadGroupToken(corpid, secret);

        try {
//            String access_token = "Mz-R9jeNraNg81oNbEjcZkGgZ_pdZ76gEagiH-J3ZtwUL0xE_gL9CXpkur7ZkoXXvkV_GQcGH8Z2RoL5nLbiWR2ULPGFQ15NQ-S7ouXIeX_aAJj8LiQZ84FEdk8MEGCz2UKL8r4H4l2mQMcRcuG9iRgEunlm36cOEN3Te3Xi_Z7dwJOpAH8Z6wbpoKiBxW7uX26PTfEFGtwNeM9ExHAxfw";
            List<Map<String, Object>> list = new ArrayList<>();
            /**消息请求地址**/
            String postUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + accessToken;
            for (int i = 0; i < tousers.length; i++) {
                /**请求参数**/
                JSONObject json = new JSONObject();

                JSONObject mainTitle = new JSONObject();
                mainTitle.put("title", title);

                JSONObject jsonCard = new JSONObject();
                jsonCard.put("type", 1);
                jsonCard.put("url", urls[i]);

                JSONObject bjson = new JSONObject();
                bjson.put("text", "待审核");
                bjson.put("style", 1);
                bjson.put("type", 1);
                bjson.put("url", urls[i]);
                bjson.put("key", "btn_key");
                JSONArray bArr = new JSONArray();
                bArr.add(bjson);

                JSONObject templateCard = new JSONObject();
                templateCard.put("card_type", msgType);
                templateCard.put("card_action", jsonCard);
                templateCard.put("sub_title_text", subTitle);
                templateCard.put("task_id", UUID.randomUUID().toString());
                templateCard.put("main_title", mainTitle);
                templateCard.put("button_list", bArr);
                templateCard.put("horizontal_content_list", jsonArray);


                json.put("touser", tousers[i]);
                json.put("msgtype", "template_card");
                json.put("agentid", agent);
                json.put("template_card", templateCard);

                /**请求结果**/
                String result = HttpRequestHelper.senPostJson(postUrl, json.toJSONString());

                System.out.println(result);
                JSONObject obj = JSONObject.parseObject(result);
                Integer code = obj.getInteger("errcode");
                if(code == 0){
                    Map<String, Object> map = new HashMap<>();
                    map.put("code", obj.getString("response_code"));
                    map.put("url", urls[i]);
                    map.put("user", tousers[i]);
                    list.add(map);
                } else if (code == 42001 || code == 40014 || code == 41001){//token失效
                    log.error("企业微信用户验证token失效，重新获取token");
                    redisUtils.remove(tokenKey);
                    loadGroupToken(corpid, secret);
                    return sendBatchButtonMessage(corpid, secret, agent, msgType, title, subTitle, jsonArray, tousers, urls);
                } else {
                    log.error("企业微信推送信息失败：" + result);
                    continue;
                }
            }

            return list;
        } catch (Exception e) {
            log.error("获取企业微信用户信息失败：" + e.getMessage(), e);
            return null;
        }
    }

    /**
     * 发送按钮消息
     * @param corpid 企业微信ID
     * @param secret 密匙
     * @param agent 应用ID
     * @param touser 发送用户(多个|隔开)
     * @param msgType 消息类型(见企业微信文档)
     * @param title 标题
     * @param subTitle 副标题
     * @param jsonArray 发送内容
     * @param url 跳转url
     * @return
     */
    public static String sendButtonMessage(String corpid, String secret, String agent, String touser, String msgType,
                                           String title, String subTitle, JSONArray jsonArray, String url) {
        if (StringUtils.isNull(corpid))
            corpid = corpID;
        if (StringUtils.isNull(secret))
            secret = corpSecret;
        if (StringUtils.isNull(agent))
            agent = agentId;
        if (StringUtils.isNull(msgType))
            msgType = "button_interaction";
//        if (jsonArray == null || jsonArray.size() == 0)
//            return "";

        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        String tokenKey = corpid + "_" + accessTokenKey;
        String accessToken = "";
        if(redisUtils.exists(tokenKey))
            accessToken = StringUtils.convertString(redisUtils.get(tokenKey));
        else
            accessToken = loadGroupToken(corpid, secret);
        /**请求参数**/
        JSONObject json = new JSONObject();

        JSONObject mainTitle = new JSONObject();
        mainTitle.put("title", title);

        JSONObject jsonCard = new JSONObject();
        jsonCard.put("type", 1);
        jsonCard.put("url", url);

        JSONObject bjson = new JSONObject();
        bjson.put("text", "待审核");
        bjson.put("style", 1);
        bjson.put("type", 1);
        bjson.put("url", url);
        bjson.put("key", "btn_key");
        JSONArray bArr = new JSONArray();
        bArr.add(bjson);

        JSONObject templateCard = new JSONObject();
        templateCard.put("card_type", msgType);
        templateCard.put("card_action", jsonCard);
        templateCard.put("sub_title_text", subTitle);
        templateCard.put("task_id", UUID.randomUUID().toString());
        templateCard.put("main_title", mainTitle);
        templateCard.put("button_list", bArr);
        templateCard.put("horizontal_content_list", jsonArray);


        json.put("touser", touser);
        json.put("msgtype", "template_card");
        json.put("agentid", agent);
        json.put("template_card", templateCard);
        System.out.println(json);
        try {
//            String access_token = "Mz-R9jeNraNg81oNbEjcZkGgZ_pdZ76gEagiH-J3ZtwUL0xE_gL9CXpkur7ZkoXXvkV_GQcGH8Z2RoL5nLbiWR2ULPGFQ15NQ-S7ouXIeX_aAJj8LiQZ84FEdk8MEGCz2UKL8r4H4l2mQMcRcuG9iRgEunlm36cOEN3Te3Xi_Z7dwJOpAH8Z6wbpoKiBxW7uX26PTfEFGtwNeM9ExHAxfw";
            /**消息请求地址**/
            String postUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + accessToken;
            /**请求结果**/
            String result = HttpRequestHelper.senPostJson(postUrl, json.toJSONString());
            System.out.println(result);
            JSONObject obj = JSONObject.parseObject(result);
            Integer code = obj.getInteger("errcode");
            if(code == 0) {
                return obj.getString("response_code");
            } else if (code == 42001 || code == 40014 || code == 41001){//token失效
                log.error("企业微信用户验证token失效，重新获取token");
                redisUtils.remove(tokenKey);
                loadGroupToken(corpid, secret);
                return sendButtonMessage(corpid, secret, agent, touser, msgType, title, subTitle, jsonArray, url);
            } else {
                log.error("企业微信推送信息失败：" + result);
                return "";
            }
        } catch (Exception e) {
            log.error("获取企业微信用户信息失败：" + e.getMessage(), e);
            return "";
        }
    }

    /**
     * 根据CODE获取用户信息
     * @param corpid 企业微信应用ID
     * @param secret 应用secret
     * @param code 企业微信授权code
     * @return
     */
    public static String getUserId(String code, String corpid, String secret){
        if (StringUtils.isNull(corpid))
            corpid = corpID;
        if (StringUtils.isNull(secret))
            secret = corpSecret;
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        String tokenKey = corpid + "_" + accessTokenKey;
        if(!redisUtils.exists(tokenKey))
            loadGroupToken(corpid, secret);

        Map<String, String> params = new HashMap<String, String>();
        params.put("code", code);
        String access_token = StringUtils.convertString(redisUtils.get(tokenKey));
        String url = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=" + access_token + "&code=" + code;
        try {
            log.error("根据CODE获取用户信息url:{},code:{},access_token:{}", url, code, access_token);
            String res = HttpRequestHelper.get(url);
            JSONObject obj = JSONObject.parseObject(res);
            log.error("根据CODE获取用户信息object:{}", res);
            Integer c = obj.getInteger("errcode");
            if(c == 0){
                return obj.getString("UserId");
            } else if (c == 42001 ){//token失效
                log.error("企业微信用户验证token失效，重新获取token");
                redisUtils.remove(tokenKey);
                loadGroupToken(corpid, secret);
                return getUserId(code, corpid, secret);
            } else if(c == 40029){
                log.error("企业微信用户验证code失效");
                return null;
            } else if(c == 40014 || c == 41001){
                log.error("企业微信用户验证token失效，重新获取token");
                redisUtils.remove(tokenKey);
                loadGroupToken(corpid, secret);
                return getUserId(code, corpid, secret);
            } else {
                log.error("企业微信用户验证失败：" + res);
                return null;
            }
        } catch (Exception e) {
            log.error("获取企业微信用户信息失败：" + e.getMessage(), e);
            return null;
        }

    }

    /**
     *  加载企业微信的token
     * @param corpid 企业微信应用ID
     * @param secret 应用secret
     */
    public static String loadGroupToken(String corpid, String secret) {
        if (StringUtils.isNull(corpid))
            corpid = corpID;
        if (StringUtils.isNull(secret))
            secret = corpSecret;
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        /**缓存key**/
        String tokenKey = corpid + "_" + accessTokenKey;
        if (redisUtils.exists(tokenKey))
            return StringUtils.convertString(redisUtils.get(tokenKey));

        String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpid + "&corpsecret=" + secret;

        try {
            String res = HttpRequestHelper.get(url);
            JSONObject obj = JSONObject.parseObject(res);
            log.error("企业微信获取access_token:{},token_url:{}", res, url);
            if("ok".equals(obj.getString("errmsg"))){
                log.info("验证后的access_token:{}", obj.getString("access_token"));
                redisUtils.set(tokenKey, obj.getString("access_token"), sessionExpired);
                return obj.getString("access_token");
            } else {
                log.error("获取企业微信API token失败：" + res);
                return "";
            }
        } catch (Exception e) {
            log.error("获取企业微信API token失败：" + e.getMessage(), e);
            return "";
        }
    }

    /**
     *  加载企业微信的token
     * @param corpid 企业微信应用ID
     * @param originSecret 应用修改部门secret
     */
    public static String loadGroupOriginToken(String corpid, String originSecret) {
        if (StringUtils.isNull(corpid))
            corpid = corpID;
        if (StringUtils.isNull(originSecret))
            originSecret = corpOriginSecret;
        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        String tokenKey = corpid + "_" +accessOriginTokenKey;
        if (redisUtils.exists(tokenKey))
            return StringUtils.convertString(redisUtils.get(tokenKey));

        String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + corpid + "&corpsecret=" + originSecret;

        try {
            String res = HttpRequestHelper.get(url);
            JSONObject obj = JSONObject.parseObject(res);
            log.error("企业微信获取access_token:{},token_url:{}", res, url);
            if("ok".equals(obj.getString("errmsg"))){
                log.info("验证后的access_token:{}", obj.getString("access_token"));
                redisUtils.set(tokenKey, obj.getString("access_token"), sessionExpired);
                return obj.getString("access_token");
            } else {
                log.error("获取企业微信API token失败：" + res);
                return "";
            }
        } catch (Exception e) {
            log.error("获取企业微信API token失败：" + e.getMessage(), e);
            return "";
        }
    }

    public static Boolean sendCardMessage(String corpid, String secret, String agent, String touser, String msgType,
                                          String title, String description, String url) {
        if (StringUtils.isNull(corpid))
            corpid = corpID;
        if (StringUtils.isNull(secret))
            secret = corpSecret;
        if (StringUtils.isNull(agent))
            agent = agentId;

        RedisUtils redisUtils = SpringContextHolder.getBean("redisUtils");
        String tokenKey = corpid + "_" + accessTokenKey;
        if(!redisUtils.exists(tokenKey))
            loadGroupToken(corpid, secret);
        /**请求参数**/
        JSONObject json = new JSONObject();

        JSONObject mainTitle = new JSONObject();
        mainTitle.put("title", "智能订单审核提醒");

        JSONObject jsonCard = new JSONObject();
        jsonCard.put("type", 1);
        jsonCard.put("url", "https://surker.chixugroup.com");

        JSONArray contentList = new JSONArray();
        JSONObject json1 = new JSONObject();
        json1.put("keyname", "工程");
        json1.put("value", "测试赛11111");
        JSONObject json2 = new JSONObject();
        json2.put("keyname", "施工部位");
        json2.put("value", "34322");
        JSONObject json3 = new JSONObject();
        json3.put("keyname", "标号");
        json3.put("value", "C45");
        JSONObject json4 = new JSONObject();
        json4.put("keyname", "预约方量");
        json4.put("value", "675");
        JSONObject json5 = new JSONObject();
        json5.put("keyname", "预约时间");
        json5.put("value", "2022-12-12 12:22");
        JSONObject json6 = new JSONObject();
        json6.put("keyname", "链接");
        json6.put("value", "点击审核");
        json6.put("type", 1);
        json6.put("url", "https://surker.chixugroup.com");
        contentList.add(json1);
        contentList.add(json2);
        contentList.add(json3);
        contentList.add(json4);
        contentList.add(json5);
        contentList.add(json6);

        JSONObject templateCard = new JSONObject();
        templateCard.put("card_type", "text_notice");
        templateCard.put("card_action", jsonCard);
        templateCard.put("sub_title_text", "订单详情");
        templateCard.put("task_id", "2323dfefsejyjgjg");
        templateCard.put("main_title", mainTitle);
        templateCard.put("horizontal_content_list", contentList);


        json.put("touser", "lucky");
        json.put("msgtype", "template_card");
        json.put("agentid", agent);
        json.put("template_card", templateCard);
        try {
            String access_token = StringUtils.convertString(redisUtils.get(tokenKey));
//            String access_token = "Mz-R9jeNraNg81oNbEjcZkGgZ_pdZ76gEagiH-J3ZtwUL0xE_gL9CXpkur7ZkoXXvkV_GQcGH8Z2RoL5nLbiWR2ULPGFQ15NQ-S7ouXIeX_aAJj8LiQZ84FEdk8MEGCz2UKL8r4H4l2mQMcRcuG9iRgEunlm36cOEN3Te3Xi_Z7dwJOpAH8Z6wbpoKiBxW7uX26PTfEFGtwNeM9ExHAxfw";
            /**消息请求地址**/
            String postUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + access_token;
            /**请求结果**/
            String result = HttpRequestHelper.senPostJson(postUrl, json.toJSONString());
            System.out.println(result);
            JSONObject obj = JSONObject.parseObject(result);
            Integer code = obj.getInteger("errcode");
            if(code == 0){
                return true;
            } else if (code == 42001 || code == 40014 || code == 41001){//token失效
                log.error("企业微信用户验证token失效，重新获取token");
//                redisUtils.remove(tokenKey);
//                loadGroupToken(corpid, secret);
                return sendCardMessage(corpid, secret, agent, touser, msgType, title, description, url);
            } else {
                log.error("企业微信推送信息失败：" + result);
                return false;
            }
        } catch (Exception e) {
            log.error("获取企业微信用户信息失败：" + e.getMessage(), e);
            return false;
        }
    }
}
